#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
配置文件模块

提供系统配置管理功能
"""

import os
import json
import sys
from typing import Dict, Any, Optional
from dataclasses import dataclass, asdict
from pathlib import Path

# 添加项目根目录到路径
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if project_root not in sys.path:
    sys.path.insert(0, project_root)

from src.utils.config import get_database_config, get_database_url

@dataclass
class DatabaseConfig:
    """数据库配置"""
    def __init__(self):
        # 使用统一配置管理
        _shared_config = get_database_config()
        self.host = _shared_config.host
        self.port = _shared_config.port
        self.database = _shared_config.database
        self.username = _shared_config.username
        self.password = _shared_config.password
        self.charset = _shared_config.charset
        self.autocommit = True
        self.pool_size = 10
        self.max_overflow = 20
        self.pool_timeout = 30
        self.pool_recycle = 3600

@dataclass
class CrawlerConfig:
    """爬虫配置"""
    max_workers: int = 3
    delay_between_requests: float = 1.0
    request_timeout: int = 30
    max_retries: int = 3
    retry_delay: float = 2.0
    default_depth: int = 3
    batch_size: int = 20
    auto_crawl_interval: int = 30  # 分钟
    
    # 请求头配置
    user_agent: str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
    headers: Dict[str, str] = None
    
    def __post_init__(self):
        if self.headers is None:
            self.headers = {
                'User-Agent': self.user_agent,
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
                'Accept-Encoding': 'gzip, deflate',
                'Connection': 'keep-alive',
                'Upgrade-Insecure-Requests': '1',
            }

@dataclass
class LoggingConfig:
    """日志配置"""
    level: str = "INFO"
    log_dir: str = "logs"
    console_output: bool = True
    file_output: bool = True
    json_format: bool = False
    max_file_size: int = 10 * 1024 * 1024  # 10MB
    backup_count: int = 5
    
    # 特定模块日志级别
    module_levels: Dict[str, str] = None
    
    def __post_init__(self):
        if self.module_levels is None:
            self.module_levels = {
                'database': 'INFO',
                'crawler': 'INFO',
                'importer': 'INFO',
                'scheduler': 'INFO'
            }

@dataclass
class SystemConfig:
    """系统配置"""
    # 文件路径
    data_dir: str = "data"
    temp_dir: str = "temp"
    export_dir: str = "exports"
    
    # 性能配置
    enable_performance_monitoring: bool = True
    memory_limit_mb: int = 1024
    
    # 安全配置
    enable_ssl: bool = False
    verify_ssl: bool = True
    
    # 其他配置
    timezone: str = "Asia/Shanghai"
    encoding: str = "utf-8"

@dataclass
class AppConfig:
    """应用程序总配置"""
    database: DatabaseConfig = None
    crawler: CrawlerConfig = None
    logging: LoggingConfig = None
    system: SystemConfig = None
    
    def __post_init__(self):
        if self.database is None:
            self.database = DatabaseConfig()
        if self.crawler is None:
            self.crawler = CrawlerConfig()
        if self.logging is None:
            self.logging = LoggingConfig()
        if self.system is None:
            self.system = SystemConfig()

class ConfigManager:
    """配置管理器"""
    
    def __init__(self, config_file: str = "config.json"):
        self.config_file = config_file
        self.config: AppConfig = AppConfig()
        
        # 确保必要的目录存在
        self._ensure_directories()
    
    def _ensure_directories(self):
        """确保必要的目录存在"""
        directories = [
            self.config.logging.log_dir,
            self.config.system.data_dir,
            self.config.system.temp_dir,
            self.config.system.export_dir
        ]
        
        for directory in directories:
            os.makedirs(directory, exist_ok=True)
    
    def load_config(self, config_file: str = None) -> AppConfig:
        """加载配置文件"""
        if config_file:
            self.config_file = config_file
        
        if os.path.exists(self.config_file):
            try:
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    config_data = json.load(f)
                
                # 递归更新配置
                self._update_config_from_dict(self.config, config_data)
                
                print(f"配置文件加载成功: {self.config_file}")
                
            except Exception as e:
                print(f"加载配置文件失败: {str(e)}，使用默认配置")
        else:
            print(f"配置文件不存在: {self.config_file}，使用默认配置")
        
        # 确保目录存在
        self._ensure_directories()
        
        return self.config
    
    def save_config(self, config_file: str = None) -> bool:
        """保存配置文件"""
        if config_file:
            self.config_file = config_file
        
        try:
            config_dict = self._config_to_dict(self.config)
            
            with open(self.config_file, 'w', encoding='utf-8') as f:
                json.dump(config_dict, f, indent=2, ensure_ascii=False)
            
            print(f"配置文件保存成功: {self.config_file}")
            return True
            
        except Exception as e:
            print(f"保存配置文件失败: {str(e)}")
            return False
    
    def _config_to_dict(self, config) -> Dict[str, Any]:
        """将配置对象转换为字典"""
        if hasattr(config, '__dataclass_fields__'):
            return asdict(config)
        return config
    
    def _update_config_from_dict(self, config, config_dict: Dict[str, Any]):
        """从字典更新配置对象"""
        for key, value in config_dict.items():
            if hasattr(config, key):
                current_value = getattr(config, key)
                
                if hasattr(current_value, '__dataclass_fields__') and isinstance(value, dict):
                    # 递归更新嵌套的数据类
                    self._update_config_from_dict(current_value, value)
                else:
                    # 直接设置值
                    setattr(config, key, value)
    
    def get_database_url(self) -> str:
        """获取数据库连接URL"""
        return get_database_url()
    
    def get_database_config_dict(self) -> Dict[str, Any]:
        """获取数据库配置字典"""
        return get_database_config()
    
    def update_database_config(self, **kwargs):
        """更新数据库配置"""
        for key, value in kwargs.items():
            if hasattr(self.config.database, key):
                setattr(self.config.database, key, value)
    
    def update_crawler_config(self, **kwargs):
        """更新爬虫配置"""
        for key, value in kwargs.items():
            if hasattr(self.config.crawler, key):
                setattr(self.config.crawler, key, value)
    
    def update_logging_config(self, **kwargs):
        """更新日志配置"""
        for key, value in kwargs.items():
            if hasattr(self.config.logging, key):
                setattr(self.config.logging, key, value)
    
    def get_config_summary(self) -> str:
        """获取配置摘要"""
        summary = []
        summary.append("=== 配置摘要 ===")
        
        # 数据库配置
        db = self.config.database
        summary.append(f"数据库: {db.host}:{db.port}/{db.database}")
        
        # 爬虫配置
        crawler = self.config.crawler
        summary.append(f"爬虫: {crawler.max_workers}线程, {crawler.delay_between_requests}秒延迟")
        
        # 日志配置
        logging_cfg = self.config.logging
        summary.append(f"日志: {logging_cfg.level}级别, 目录={logging_cfg.log_dir}")
        
        # 系统配置
        system = self.config.system
        summary.append(f"系统: 数据目录={system.data_dir}, 时区={system.timezone}")
        
        return "\n".join(summary)

# 全局配置管理器实例
_config_manager: Optional[ConfigManager] = None

def get_config_manager(config_file: str = "config.json") -> ConfigManager:
    """获取全局配置管理器"""
    global _config_manager
    if _config_manager is None:
        _config_manager = ConfigManager(config_file)
        _config_manager.load_config()
    return _config_manager

def get_config() -> AppConfig:
    """获取应用配置"""
    return get_config_manager().config

def load_config_from_env():
    """从环境变量加载配置"""
    config_manager = get_config_manager()
    
    # 数据库配置
    if os.getenv('DB_HOST'):
        config_manager.update_database_config(
            host=os.getenv('DB_HOST'),
            port=int(os.getenv('DB_PORT', 3306)),
            database=os.getenv('DB_DATABASE', 'tianyi_webdav'),
            username=os.getenv('DB_USERNAME', 'tianyi_webdav'),
            password=os.getenv('DB_PASSWORD', 'tPjwSXhJEA5Nyb8Y')
        )
    
    # 爬虫配置
    if os.getenv('CRAWLER_MAX_WORKERS'):
        config_manager.update_crawler_config(
            max_workers=int(os.getenv('CRAWLER_MAX_WORKERS')),
            delay_between_requests=float(os.getenv('CRAWLER_DELAY', 1.0)),
            request_timeout=int(os.getenv('CRAWLER_TIMEOUT', 30))
        )
    
    # 日志配置
    if os.getenv('LOG_LEVEL'):
        config_manager.update_logging_config(
            level=os.getenv('LOG_LEVEL'),
            log_dir=os.getenv('LOG_DIR', 'logs')
        )

def create_default_config_file(config_file: str = "config.json"):
    """创建默认配置文件"""
    config_manager = ConfigManager(config_file)
    config_manager.save_config()
    print(f"默认配置文件已创建: {config_file}")

if __name__ == "__main__":
    # 创建默认配置文件
    create_default_config_file()
    
    # 测试配置加载
    config_manager = get_config_manager()
    print(config_manager.get_config_summary())
    
    # 测试环境变量加载
    os.environ['DB_HOST'] = '127.0.0.1'
    os.environ['LOG_LEVEL'] = 'DEBUG'
    load_config_from_env()
    
    print("\n更新后的配置:")
    print(config_manager.get_config_summary())